Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to reuse Vec<T> backing storage for Rc/Arc<[T]> #104205

Merged
merged 2 commits into from
Nov 17, 2022

Conversation

clubby789
Copy link
Contributor

If a Vec<T> has sufficient capacity to store the inner RcBox<[T]>, we can just reuse the existing allocation and shift the elements up, instead of making a new allocation.

@rustbot
Copy link
Collaborator

rustbot commented Nov 9, 2022

r? @thomcc

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Nov 9, 2022
@rustbot
Copy link
Collaborator

rustbot commented Nov 9, 2022

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@joboet
Copy link
Contributor

joboet commented Nov 9, 2022

Cool idea! However, this is unfortunately unsound, since the RcBox will in most cases deallocate with a different layout than that which the Vec was allocated with. Reusing the allocation is possible, but it needs to be shrunk or grown where appropriate.

@clubby789
Copy link
Contributor Author

This might not actually be very useful, since Global::shrink reallocates and copies so it's only faster when the allocation is exactly the right size.

@the8472
Copy link
Member

the8472 commented Nov 10, 2022

Many allocators have some slack, a shrink that only shrinks by a few bytes may not require any reallocation at all. And for large allocations it may be implemented as mremap(2) or munmap(2) on the tail.

library/alloc/src/rc.rs Outdated Show resolved Hide resolved
library/alloc/src/rc.rs Outdated Show resolved Hide resolved
@thomcc
Copy link
Member

thomcc commented Nov 13, 2022

This was pretty subtle and tricky to review. It's disappointing that this kind of thing is hard with our allocator APIs... But it looks fine to me.

@bors r+ rollup=never

@bors
Copy link
Contributor

bors commented Nov 13, 2022

📌 Commit 868c59fdacf6177170d686fdc4ed0a36c7469eef has been approved by thomcc

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 13, 2022
@the8472
Copy link
Member

the8472 commented Nov 13, 2022

This could use a test that verifies that the allocation gets reused. That'll also allow miri to look at this optimization.

@thomcc
Copy link
Member

thomcc commented Nov 13, 2022

Hm, sure.

@bors r-

@rustbot author

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 13, 2022
@bors bors removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Nov 13, 2022
@kpreid
Copy link
Contributor

kpreid commented Nov 13, 2022

Say, could the same optimization be applied to Arc<[T]>?

@clubby789
Copy link
Contributor Author

Added a test for this behaviour, but I suspect not all platforms will implement realloc in this way so it might have to be skipped on some.

@rustbot rustbot added the A-testsuite Area: The testsuite used to check the correctness of rustc label Nov 14, 2022
Co-authored-by: joboet <jonas.boettiger@icloud.com>
@clubby789
Copy link
Contributor Author

Also added the optimization to Arc since it's implemented very similarly.
I raised the src/test/ui limit since none of the existing directories looked quite appropriate for checking std implementation details - maybe src/test/ui/allocator?

@thomcc
Copy link
Member

thomcc commented Nov 14, 2022

Definitely uitests are the wrong place for this. Just put it in https://github.com/rust-lang/rust/tree/master/library/alloc/tests somewhere.

@clubby789
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 14, 2022
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 14, 2022
@thomcc
Copy link
Member

thomcc commented Nov 16, 2022

Looks fine

@bors r+

@bors
Copy link
Contributor

bors commented Nov 16, 2022

📌 Commit 8424c24 has been approved by thomcc

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 16, 2022
@klensy
Copy link
Contributor

klensy commented Nov 16, 2022

Need to update title and description, as it now affects Arc too?

@Manishearth
Copy link
Member

@bors p=1

going to close the tree for non-nevers for a while so they can drain out

@clubby789 clubby789 changed the title Attempt to reuse Vec<T> backing storage for Rc<[T]> Attempt to reuse Vec<T> backing storage for Rc/Arc<[T]> Nov 17, 2022
@bors
Copy link
Contributor

bors commented Nov 17, 2022

⌛ Testing commit 8424c24 with merge 36db030...

@bors
Copy link
Contributor

bors commented Nov 17, 2022

☀️ Test successful - checks-actions
Approved by: thomcc
Pushing 36db030 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 17, 2022
@bors bors merged commit 36db030 into rust-lang:master Nov 17, 2022
@rustbot rustbot added this to the 1.67.0 milestone Nov 17, 2022
@@ -210,3 +210,18 @@ fn weak_may_dangle() {
// `val` dropped here while still borrowed
// borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak`
}

#[test]
fn arc_from_vec_opt() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is UB in this test: #104565.

@RalfJung
Copy link
Member

This could use a test that verifies that the allocation gets reused. That'll also allow miri to look at this optimization.

Good thing you did that, Miri found a bug. :) Though I think only the test is buggy, not the implementation.
(Also FWIW, only lib tests are run by Miri, ui tests are not.)

bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 19, 2022
Revert Vec/Rc storage reuse opt

Remove the optimization for using storage added by rust-lang#104205.
The perf wins were pretty small, and it relies on non-guarenteed behaviour. On platforms that don't implement shrinking in place, the performance will be significantly worse.

While it could be gated to platforms that do this (such as GNU), I don't think it's worth the overhead of maintaining it for very small gains. (rust-lang#104565, rust-lang#104563)

cc `@RalfJung` `@matthiaskrgr`

Fixes rust-lang#104565
Fixes rust-lang#104563
Aaron1011 pushed a commit to Aaron1011/rust that referenced this pull request Jan 6, 2023
Attempt to reuse `Vec<T>` backing storage for `Rc/Arc<[T]>`

If a `Vec<T>` has sufficient capacity to store the inner `RcBox<[T]>`, we can just reuse the existing allocation and shift the elements up, instead of making a new allocation.
Aaron1011 pushed a commit to Aaron1011/rust that referenced this pull request Jan 6, 2023
Revert Vec/Rc storage reuse opt

Remove the optimization for using storage added by rust-lang#104205.
The perf wins were pretty small, and it relies on non-guarenteed behaviour. On platforms that don't implement shrinking in place, the performance will be significantly worse.

While it could be gated to platforms that do this (such as GNU), I don't think it's worth the overhead of maintaining it for very small gains. (rust-lang#104565, rust-lang#104563)

cc `@RalfJung` `@matthiaskrgr`

Fixes rust-lang#104565
Fixes rust-lang#104563
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants